package model.management;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import model.entity.Product;

import org.junit.Before;
import org.junit.Test;

import common.Barcode;
import common.Result;
import common.Size;

public class ProductManagerTest
{

  private Product nullProduct;
  private Product validProduct;
  private Product invalidProduct;

  @Before
  public void setUp()
  {
    nullProduct = null;
    validProduct = new Product(new Barcode(), "RelativeFinder", new Size(), 1, 1);
    invalidProduct = new Product(new Barcode(), "", new Size(), -1, -1);
    ProductManager.getProducts().clear();
  }

  @Test
  public void testValidateAddProduct()
  {

    // invalid-null product
    Result result = ProductManager.validateAddProduct(nullProduct);
    assertFalse(result.getStatus());

    // invalid-invalid product
    Result result2 = ProductManager.validateAddProduct(invalidProduct);
    assertFalse(result2.getStatus());

    // valid
    Result result3 = ProductManager.validateAddProduct(validProduct);
    assertTrue(result3.getStatus());

    // invalid-already exist
    ProductManager.addProduct(validProduct);
    Result result4 = ProductManager.validateAddProduct(validProduct);
    assertFalse(result4.getStatus());

  }

  @Test
  public void testAddProdcut()
  {

    // invalid
    Result result = ProductManager.addProduct(nullProduct);
    assertEquals(0, ProductManager.getProducts().size());
    assertFalse(result.getStatus());

    // valid
    Result result2 = ProductManager.addProduct(validProduct);
    assertEquals(1, ProductManager.getProducts().size());
    assertTrue(result2.getStatus());

  }

  @Test
  public void testValidateRemoveProduct()
  {

    // invalid-null product
    Result result = ProductManager.validateRemoveProduct(nullProduct);
    assertFalse(result.getStatus());

    // valid
    ProductManager.addProduct(validProduct);
    Result result3 = ProductManager.validateRemoveProduct(validProduct);
    assertTrue(result3.getStatus());

    // invalid-doesn't exist
    Result result4 = ProductManager.validateRemoveProduct(invalidProduct);
    assertFalse(result4.getStatus());

  }

  @Test
  public void testRemoveProdcut()
  {

    // invalid
    ProductManager.addProduct(validProduct);
    Result result = ProductManager.removeProduct(nullProduct);
    assertEquals(1, ProductManager.getProducts().size());
    assertFalse(result.getStatus());

    // valid
    Result result2 = ProductManager.removeProduct(validProduct);
    assertEquals(0, ProductManager.getProducts().size());
    assertTrue(result2.getStatus());

  }

  @Test
  public void testValidateUpdateProduct()
  {

    // invalid-null product
    Result result = ProductManager.validateUpdateProduct(validProduct, nullProduct);
    assertFalse(result.getStatus());

    Result result2 = ProductManager.validateUpdateProduct(nullProduct, validProduct);
    assertFalse(result2.getStatus());

    // invalid-invalid new product
    Result result3 = ProductManager.validateUpdateProduct(validProduct, invalidProduct);
    assertFalse(result3.getStatus());

    // invalid-old product doesn't exist
    Result result4 = ProductManager.validateUpdateProduct(validProduct, validProduct);
    assertFalse(result4.getStatus());

    // valid
    ProductManager.addProduct(validProduct);
    Result result5 = ProductManager.validateUpdateProduct(validProduct, validProduct);
    assertTrue(result5.getStatus());

  }

  @Test
  public void testUpdateProdcut()
  {

    Product oldProduct = new Product(new Barcode(), "RelativeFinder", new Size(), 1, 1);
    Product newProduct = new Product(new Barcode(), "New", new Size(), 3, 5);

    ProductManager.addProduct(oldProduct);

    // invalid
    Result result = ProductManager.updateProduct(oldProduct, nullProduct);
    assertTrue(ProductManager.getProducts().contains(oldProduct));
    assertFalse(ProductManager.getProducts().contains(nullProduct));
    assertEquals(1, ProductManager.getProducts().size());
    assertFalse(result.getStatus());

    // valid
    Result result2 = ProductManager.updateProduct(oldProduct, newProduct);
    assertFalse(ProductManager.getProducts().contains(oldProduct));
    assertTrue(ProductManager.getProducts().contains(newProduct));
    assertEquals(1, ProductManager.getProducts().size());
    assertTrue(result2.getStatus());

  }

}
